<html>
<head><meta charset="utf-8"><title>Set the size of a fieldless enum with a type alias · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html">Set the size of a fieldless enum with a type alias</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="217410734"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217410734" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217410734">(Nov 20 2020 at 14:56)</a>:</h4>
<p>Hello <span aria-label="hello" class="emoji emoji-1f44b" role="img" title="hello">:hello:</span> !</p>
<p>When making an abstraction crate over a C API, it is often useful to transform a C integer to a Rust enum when the API says that the value must be one of the possibilities described.<br>
Usually I would create a new enum and conversions to/from the C equivalent type. However in some cases it is useful to have the Rust type share the same memory representation than the C one so it can be used directly on the API.</p>
<p>The <code>repr(u*)</code> attribute is very useful for that to set the size of fieldless enums to match the size of the C type. It's fine when the size of the C types are <em>fixed</em> in the API but it is not useful if the C type is one of the <code>int</code>, <code>long</code>, etc which size depend on the compilation target.</p>
<p>For example if in my C API I have:</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code><span class="k">typedef</span> <span class="kt">long</span> <span class="kt">int</span> <span class="n">fruit_t</span><span class="p">;</span>
</code></pre></div>
<p>and the API says that <code>fruit_t</code> can either be <code>1</code> (orange), <code>2</code> (apple) or <code>3</code> (kiwi).</p>
<p><code>bindgen</code> will generate:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">type</span> <span class="nc">fruit_t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="c1">// depends on the platform</span>
</code></pre></div>
<p>I would like to do:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">Fruit</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Orange</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Apple</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Kiwi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>and fix the size of that <code>Fruit</code> type to be <code>fruit_t</code> so that it would be correct on every target!</p>
<p>For example, could <code>#[repr(fruit_t)]</code> be a thing?</p>



<a name="217419081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217419081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217419081">(Nov 20 2020 at 15:56)</a>:</h4>
<p>This seems very brittle, because this means that your ABI depends not only from the plateform (Linux arm, Windows amd64, …), but also from the compiler that you are using for compiling your C sources. AFAIK gcc and msvc don't have the same size for <code>long</code> on the same plateform.</p>
<p>I think that I would create a <a href="http://build.rs">build.rs</a> script that would detect the size of the various kind of integer you need (<code>int</code>, <code>long</code>, …), and set a feature for each possible value (like <code>unsigned_long_is_64bits</code> or <code>unsigned_long_is_32_bits</code>), then use something like (not tested)</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[cfg_attr(unsigned_long_is_64bits, repr(u64)]</span><span class="w"></span>
<span class="cp">#[cfg_attr(unsigned_long_is_32bits, repr(u32)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">Fruit</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Orange</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Apple</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Kiwi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="217420883"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217420883" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217420883">(Nov 20 2020 at 16:07)</a>:</h4>
<p>Ah that is a good idea indeed! Thanks for the answer, I will definitely be able to do that.</p>



<a name="217422109"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217422109" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217422109">(Nov 20 2020 at 16:15)</a>:</h4>
<p>I am not familiar at all with features and <code>cfg()</code>, but it seems that we can also assign a value (instead of just using them as flag), so maybe you could have a feature <code>sizeof_unsigned_long</code> set to <code>32</code> or <code>64</code> depending on the platform, then <code>#[cfg_attr(sizeof_unsign_long == 32, repr(u32)] #[cfg_attr(sizeof_unsign_long == 64, repr(u64)]</code>.</p>



<a name="217423819"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217423819" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217423819">(Nov 20 2020 at 16:27)</a>:</h4>
<p>In case you don't know, it's really easy to compile programs directly from heredoc in shell:</p>
<div class="codehilite" data-code-language="Bash"><pre><span></span><code><span class="nv">SIZE</span><span class="o">=</span><span class="k">$(</span>gcc <span class="s">&lt;&lt;EOF -x c - -o binary &amp;&amp; ./binary</span>
<span class="s">#include&lt;stdio.h&gt;</span>
<span class="s">int main() {</span>
<span class="s">    printf("%d", sizeof(unsigned long) * 8);</span>
<span class="s">}</span>
<span class="s">EOF</span>
<span class="k">)</span>
</code></pre></div>
<p>This will compile the file, run it, the assign the value to the variable <code>SIZE</code>.</p>
<p>Another option is:</p>
<div class="codehilite" data-code-language="Bash"><pre><span></span><code><span class="nv">SIZE</span><span class="o">=</span><span class="k">$(</span>gcc <span class="s">&lt;&lt;EOF -x c - -o binary &amp;&amp; ./binary; echo $?</span>
<span class="s">int main() {</span>
<span class="s">    return sizeof(unsigned long) * 8;</span>
<span class="s">}</span>
<span class="s">EOF</span>
<span class="k">)</span>
</code></pre></div>



<a name="217423941"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217423941" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217423941">(Nov 20 2020 at 16:27)</a>:</h4>
<p>Why isn't <code>std::mem::size_of::&lt;c_long&gt;()</code> enough?</p>



<a name="217424428"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424428" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424428">(Nov 20 2020 at 16:30)</a>:</h4>
<p>I need to double check, but I don't think that <code>mingw</code>, <code>clang</code> (for Windows) and <code>msvc</code> have the same value for it on Windows. So <code>std::mem::size_of::&lt;c_long&gt;()</code> can't give the right answer since there is no right answer.</p>



<a name="217424509"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424509" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424509">(Nov 20 2020 at 16:31)</a>:</h4>
<p>those target different ABIs though</p>



<a name="217424564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424564">(Nov 20 2020 at 16:31)</a>:</h4>
<p>you can't target multiple C ABIs with the same Rust target</p>



<a name="217424675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424675">(Nov 20 2020 at 16:32)</a>:</h4>
<p>in that case <code>std::mem::size_of::&lt;c_long&gt;()</code> is perfectly good. I didn't realized that this was included in the target ABI.</p>



<a name="217424780"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424780" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424780">(Nov 20 2020 at 16:33)</a>:</h4>
<p><span aria-label="face palm" class="emoji emoji-1f926" role="img" title="face palm">:face_palm:</span> target <strong>triple</strong>…</p>



<a name="217424812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217424812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robin Moussu <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217424812">(Nov 20 2020 at 16:33)</a>:</h4>
<p>At least I learned!</p>



<a name="217528664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217528664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Noah Lev <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217528664">(Nov 22 2020 at 01:40)</a>:</h4>
<p>Side note: Not a big deal, but these discussions are more suited to <a class="stream" data-stream-id="122651" href="/#narrow/stream/122651-general">#general</a> or <a class="stream" data-stream-id="131828" href="/#narrow/stream/131828-t-compiler">#t-compiler</a>. This stream is for help with <em>developing</em> the compiler.</p>



<a name="217530541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217530541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217530541">(Nov 22 2020 at 02:43)</a>:</h4>
<p>someone privileged could make this channel <code>t-compiler/dev-qa</code></p>



<a name="217639301"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Set%20the%20size%20of%20a%20fieldless%20enum%20with%20a%20type%20alias/near/217639301" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Set.20the.20size.20of.20a.20fieldless.20enum.20with.20a.20type.20alias.html#217639301">(Nov 23 2020 at 15:12)</a>:</h4>
<p>Oops sorry for the wrong channel. Will think about it next time.</p>
<p>Thanks for the messages! Setting the features with <code>size_of</code> seems to be the most convenient. I guess being able to do <code>#[repr()]</code> with typedefs would be nice to have but the problem can be overcome with that.<br>
Currently we are defining transparent newtype wrappers with public <code>const</code> defined:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(transparent)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Fruit</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">val</span>: <span class="nc">fruit_t</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">impl</span><span class="w"> </span><span class="n">Fruit</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">ORANGE</span>: <span class="nc">Fruit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Fruit</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">val</span>: <span class="mi">1</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>